home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
encorsrc.lha
/
encore_sources
/
sys
/
n32kernel.t
< prev
next >
Wrap
Text File
|
1988-05-02
|
26KB
|
673 lines
(herald n32kernel (env tsys)) ;86/12/21
;;; note that A1 must not be destroyed
;;; return is in TP
(define (n32-big-bang) ;86/12/24
(lap (big_bang handle-stack-base
icall-bad-proc icall-wrong-nargs
handle-undefined-effect
really-gc pc-code-vector
heap-overflow-error call-fault-handler cont-wrong-nargs)
(spri d nil-reg (d@r nil-reg slink/nil-cdr)) ; (cdr '()) = '()
(spri d nil-reg (d@r nil-reg slink/nil-car)) ; (car '()) = '()
(movi d P (d@r nil-reg slink/kernel)) ; save kernel pointer
(addr (label %undefined-effect) (d@r nil-reg slink/undefined-effect))
(addr (label %make-pair) (d@r nil-reg slink/make-pair))
(addr (label %make-extend) (d@r nil-reg slink/make-extend))
(addr (label %nary-setup) (d@r nil-reg slink/nary-setup))
(addr (label %set) (d@r nil-reg slink/set))
(addr (label %icall) (d@r nil-reg slink/icall))
(addr (label %cit-hack) (d@r nil-reg slink/cit-hack))
(addr (label %cont-wrong-nargs) (d@r nil-reg slink/cont-wrong-nargs))
(addr (label %kernel-begin) (d@r nil-reg slink/kernel-begin))
(addr (label %kernel-end) (d@r nil-reg slink/kernel-end))
;; initialize root process, stored in outer space?
;; zero out extra registers
(movi d ($ temp-block-size) S0)
initialize-loop
(movi d ($ 0) (tos))
(subi d ($ 4) S0)
(cmpi d S0 ($ 0))
(j> initialize-loop)
(spri d SP A3) ; load task reg
(lpri d TASK A3) ; in a roundabout way
(adjspi d ($ (fx- 0 (fx+ %%task-header-offset 4)))) ; allocate task block
(movi d ($ header/task) (tos)) ; task header
(spri d SP A3)
(addi d ($ 2) A3)
(movi d A3 (d@r nil-reg slink/root-process)) ; ptr to root and
(movi d A3 (d@r nil-reg slink/current-task)) ; current process
;; initialize stack
(movi d A3 (tos)) ; task block
(spri d nil-reg (tos)) ; no parent
(movi d ($ 0) (tos)) ; active, no current sz
(movi d ($ (fixnum-ashl %%stack-size 2)) (tos)) ; total stack size
(movi d ($ #xBADBAD) (tos)) ; distinguished value
(addr (label stack-base-template) (tos)) ; stack base
;; initialize root process
;++ (spri d SP A3)
;++ (addi d ($ 2) A3)
;++ (movi d A3 (d@r TASK task/stack)) ; set stack in root-process
;++ what to do; task/stack is a fixnum not an extend as it should be!
(spri d SP (d@r TASK task/stack))
(movi d ($ 0) (d@r TASK task/extra-pointer))
(movi d ($ 0) (d@r TASK task/extra-scratch))
(movi d ($ 0) (d@r TASK task/scratch))
(spri d nil-reg (d@r TASK task/dynamic-state))
(spri d nil-reg (d@r TASK task/doing-gc?))
(movi d ($ 0) (d@r TASK task/foreign-call-cont))
(movi d ($ 0) (d@r TASK task/critical-count))
(spri d nil-reg (d@r TASK task/k-list))
(spri d nil-reg (d@r TASK task/gc-weak-set-list))
(spri d nil-reg (d@r TASK task/gc-weak-alist-list))
(spri d nil-reg (d@r TASK task/gc-weak-table-list))
(spri d nil-reg (d@r nil-reg slink/snapper-freelist))
(spri d nil-reg (d@r nil-reg slink/pair-freelist))
(movi d (d@r P (static 'big_bang)) P)
(movi d (d@r p 2) p)
(jump (@r TP))
%make-pair
;; return pair in AN
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(movi d (d@r TASK task/area-frontier) AN) ; AN is old frontier
(addi d ($ 8) AN) ; cons 2 slots
(cmpi d AN (d@r TASK task/area-limit))
(j> %make-pair-heap-overflow)
%make-pair-continue
(movi d AN (d@r TASK task/area-frontier)) ; update frontier
(subi d ($ (fx- 8 tag/pair)) AN) ; return pair pointer
(movi d ($ 0) (d@r AN (fx- 0 tag/pair))) ; zero out CDR
(movi d ($ 0) (d@r AN (fx- 4 tag/pair))) ; zero out CAR
(bici b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; re-enable
(cmpi b ($ 0) (d@r TASK (fx+ task/critical-count 3)))
(jn= %deferred-interrupts)
(ret ($ 0))
%make-pair-heap-overflow
(movi d ($ header/true) (d@r TASK task/doing-gc?))
(jsr (label %heap-overflow))
(movi d (d@r TASK task/area-frontier) AN)
(addi d ($ 8) AN)
(cmpi d AN (d@r TASK task/area-limit))
(j> %horrible-heap-overflow)
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(spri d nil-reg (d@r TASK task/doing-gc?))
(jbr %make-pair-continue)
%make-extend
;; receive descriptor in An, size in S0, return extend in AN
;; NARGS is extra scratch reg
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(movi d (d@r TASK task/area-frontier) NARGS) ; NARGS is old area-frontier
(addi d ($ 4) S0) ; add one for the descriptor
(addi d NARGS S0) ; S0 now new frontier
(cmpi d S0 (d@r TASK task/area-limit))
(j> %make-extend-heap-overflow)
%make-extend-continue
(movi d S0 (d@r TASK task/area-frontier)) ; update frontier
(movi d AN (@r NARGS)) ; move in descriptor
(movi d NARGS AN) ; return extend pointer
(jbr extend-test)
extend-loop ; zero out storage
(movi d ($ 0) (@r NARGS)) ; clear slot
extend-test
(addi d ($ 4) NARGS) ; next slot (NARGS is counter)
(cmpi d S0 NARGS) ; if at frontier
(j> extend-loop) ; loop
(addi d ($ tag/extend) AN)
(bici b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3)))
(cmpi b ($ 0) (d@r TASK (fx+ task/critical-count 3)))
(jn= %deferred-interrupts)
(ret ($ 0))
%make-extend-heap-overflow
(movi d ($ header/true) (d@r TASK task/doing-gc?))
(subi d NARGS S0) ; S0 now size+1 again
(jsr (label %heap-overflow))
(movi d (d@r TASK task/area-frontier) NARGS) ; get post-gc area-frontier
(addi d NARGS S0) ; S0 now new frontier
(cmpi d S0 (d@r TASK task/area-limit))
(j> %horrible-heap-overflow)
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(spri d nil-reg (d@r TASK task/doing-gc?))
(jbr %make-extend-continue)
%heap-overflow
(movi d S0 (tos)) ; save scratch registers
(movi d NARGS (tos))
(movi d ($ (fx/ temp-block-size 4)) S0)
save-loop ; save temps
(movi d (index-d (d@r TASK -4) S0) (tos))
(subi d ($ 1) S0)
(cmpi d S0 ($ 0))
(j>= save-loop)
(movi d TP (tos)) ; save pointer registers
(movi d AN (tos))
(movi d A3 (tos))
(movi d A2 (tos))
(movi d A1 (tos))
(movi d P (tos))
(movi d (d@r SP (* (+ *no-of-registers* 3) 4)) A1) ; one for TP 2 return ;++
(addr (label pc-check-return) (tos)) ; continuation
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'pc-code-vector)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP)) ; call pc-code-vector
;;; the template header byte has high bit set if nary
%cit-hack
(movi d (d@r tp 6) an) ; get auxilliary template
(jump (@r an))
%icall
(movi w P S0)
(andi b ($ #b11) S0)
(cmpi b ($ tag/extend) S0) ; check ptr to closure is extend
(jn= %icall-bad-proc)
(movi d (d@r P -2) TP) ; fetch template header
(movi w TP S0)
(andi b ($ 3) S0) ; check header is extend
(cmpi b ($ tag/extend) S0)
(jn= %icall-bad-proc)
(cmpi b (d@r TP -2) ($ header/template)) ; check header is template
(jn= %icall-check-nary)
(cmpi b (d@r TP template/nargs) NARGS) ; check number of args
(j= %icall-ok)
(jbr %icall-wrong-nargs)
%icall-check-nary
(cmpi b (d@r TP -2) ($ (fx+ header/template 128))) ; nary if high bit set
(jn= %icall-bad-proc)
(cmpi b (d@r TP template/nargs) NARGS)
(j> %icall-wrong-nargs)
%icall-ok
(jump (@r TP))
%icall-bad-proc
(movi d a1 (d@r TASK task/t0))
(movi d a2 (d@r TASK (fx+ task/t0 4)))
(movi d a3 (d@r TASK (fx+ task/t0 8)))
(movi d ($ 0) s0)
(jsr (label %nary-setup))
(movi d an a2)
(movi d p a1)
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'icall-bad-proc)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP))
%icall-wrong-nargs
(movi d a1 (d@r TASK task/t0))
(movi d a2 (d@r TASK (fx+ task/t0 4)))
(movi d a3 (d@r TASK (fx+ task/t0 8)))
(movi d ($ 0) s0)
(jsr (label %nary-setup))
(movi d an a2)
(movi d p a1)
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'icall-wrong-nargs)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP))
%deferred-interrupts ; Build fault frame
(movi d S0 (tos)) ; save scratch registers
(movi d NARGS (tos))
(movi d ($ (fx/ (fx+ temp-block-size 8) 4)) S0)
%int-save-loop ; save temps and extra p and s
(movi d (index-d (d@r TASK -12) S0) (tos)) ; and task/scratch
(subi d ($ 1) S0)
(cmpi d S0 ($ 0))
(j>= %int-save-loop)
(movi d TP (tos)) ; save pointer registers
(movi d AN (tos))
(movi d A3 (tos))
(movi d A2 (tos))
(movi d A1 (tos))
(movi d P (tos))
(movi d ($ 0) (tos)) ; pc
(movi d (d@r SP (fx* 4 (+ *pointer-temps* *scratch-temps* 12))) (tos))
;; 12 = 2 (scratch regs) + 6 (pointer regs) + 1 (pc)
;; + 3 (extra p & s & task/scratch)
(movi d ($ 0) (tos)) ; # of pointers on stack was 0
(movi d ($ (+ (fixnum-ashl (+ *pointer-temps* *scratch-temps* 14) 8)
header/fault-frame)) ; fault frame header
(tos))
(addr (label %int-return) (tos)) ; continuation
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'call-fault-handler)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP))
%kernel-begin
%cont-wrong-nargs
(negi d nargs nargs)
(movi d a1 (d@r TASK task/t0))
(movi d a2 (d@r TASK (fx+ task/t0 4)))
(movi d a3 (d@r TASK (fx+ task/t0 8)))
(movi d ($ 0) s0)
(jsr (label %nary-setup))
(movi d an a2)
(addr (d@r sp 2) a1)
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'cont-wrong-nargs)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP))
%post-gc-nary-setup
(movi d ($ -1) (d@r TASK task/extra-scratch)) ; -1 if post-gc
(jbr %real-nary-setup)
%nary-setup ; # of required args in S0
(movi d ($ 0) (d@r TASK task/extra-scratch))
%real-nary-setup
(subi d ($ 2) NARGS) ; now NARGS = #args - 1
(movi d P (d@r TASK task/extra-pointer)) ; save P, use it as working reg
(spri d nil-reg AN) ; why??
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(jbr %nary-test)
%nary-loop ; cons the argument list
(movi d AN P) ; accumulate in P
(movi d (d@r TASK task/area-frontier) AN) ; AN is old frontier
(addi d ($ 8) AN) ; cons 2 slots
(cmpi d AN (d@r TASK task/area-limit))
(j> %nary-make-pair-heap-overflow)
%nary-make-pair-continue
(movi d AN (d@r TASK task/area-frontier)) ; update frontier
(subi d ($ (fx- 8 tag/pair)) AN) ; return pair pointer
(movi d ($ 0) (d@r AN (fx- 0 tag/pair))) ; zero out CDR
(movi d P (d@r AN -3)) ; set cdr
(movi d (index-d (@r TASK) NARGS) (d@r AN 1)) ; set car
(subi d ($ 1) NARGS)
%nary-test
(cmpi d NARGS S0)
(j>= %nary-loop)
(cmpi d ($ 0) (d@r TASK task/extra-scratch))
(jn= %nary-clear-extras)
(movi d (d@r TASK task/extra-pointer) P) ; restore P and return
(bici b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3)))
(cmpi b ($ 0) (d@r TASK (fx+ task/critical-count 3)))
(jn= %deferred-interrupts)
(ret ($ 0))
%nary-clear-extras ; if more args than A registers,
(cmpi d ($ 3) S0) ; they're in memory. Clear.
(j<= foo45)
(movi d ($ 3) S0)
foo45
(movi d ($ 0) (index-d (@r TASK) S0))
(addi d ($ 1) S0)
(cmpi d ($ (fx/ temp-block-size 4)) S0) ; why clear whole block??
(j> foo45)
(addr (label %nary-setup) (d@r nil-reg slink/nary-setup)) ; why?? redundant?
(movi d (d@r TASK task/extra-pointer) P)
(bici b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3)))
(cmpi b ($ 0) (d@r TASK (fx+ task/critical-count 3)))
(jn= %deferred-interrupts)
(ret ($ 0))
%nary-make-pair-heap-overflow
(movi d ($ header/true) (d@r TASK task/doing-gc?))
(jsr (label %heap-overflow))
(movi d (d@r TASK task/area-frontier) AN)
(addi d ($ 8) AN)
(cmpi d AN (d@r TASK task/area-limit))
(j> %horrible-heap-overflow)
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(spri d nil-reg (d@r TASK task/doing-gc?))
(jbr %nary-make-pair-continue)
%set ; a location is (unit . index)
;; vcell in extra-pointer
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(movi d s0 (tos))
(movi d an (tos))
(movi d a3 (tos))
(movi d a2 (tos))
(movi d a1 (tos))
(movi d p (tos))
(movi d (d@r TASK task/extra-pointer) a3)
(movi d (d@r A3 6) A1) ; get locations
(movi d (d@r A1 2) A1) ; get the vector in A1
(movi d (d@r A1 -2) S0)
(ashi d ($ -8) S0) ; length in S0
(jbr %set-test)
%set-loop
(movi d (d@r nil-reg slink/snapper-freelist) an)
(cmpi d an (d@r nil-reg 1))
(j= cons-snapper)
(movi d (d@r an 1) p)
(movi d (d@r an -3) (d@r nil-reg slink/snapper-freelist))
(movi d (d@r nil-reg slink/pair-freelist) (d@r an -3))
(movi d an (d@r nil-reg slink/pair-freelist))
%real-top
(movi d (index-d (d@r A1 -6) S0) A2) ; get unit
(movi d (index-d (d@r A1 -2) S0) AN) ; get index
(movi d (d@r a3 2) (d@r p 2))
(movi d a2 (d@r p 6))
(movi d an (d@r p 10))
(movi d p (index-b (d@r A2 2) AN))
(subi d ($ 2) S0)
%set-test
(cmpi d ($ 0) S0)
(jn= %set-loop)
(movi d (tos) p)
(movi d (tos) a1)
(movi d (tos) a2)
(movi d (tos) a3)
(movi d (tos) an)
(movi d (tos) s0)
(bici b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3)))
(cmpi b ($ 0) (d@r TASK (fx+ task/critical-count 3)))
(jn= %deferred-interrupts)
(ret ($ 0))
cons-snapper
(movi d (d@r TASK task/area-frontier) AN)
(addi d ($ 16) AN)
(cmpi d AN (d@r TASK task/area-limit))
(j> %set-heap-overflow)
%set-continue ; lose, lose
(movi d AN (d@r TASK task/area-frontier))
(addr (d@r an -14) p)
(addr (label link-snapper) a2)
(movi d a2 (d@r p -2))
(jbr %real-top)
%set-heap-overflow
(movi d ($ header/true) (d@r TASK task/doing-gc?))
(movi d ($ (+ (fixnum-ashl 5 16) (fixnum-ashl 1 8) header/vframe )) (tos))
(movi d (d@r sp 24) (tos))
(jsr (label %heap-overflow))
(movi d (@r sp) (d@r sp 28))
(adjspi b ($ -8))
(movi d (d@r TASK task/area-frontier) AN)
(addi d ($ 16) AN)
(cmpi d AN (d@r TASK task/area-limit))
(j> %horrible-heap-overflow)
(ori b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3))) ; defer int's
(spri d nil-reg (d@r TASK task/doing-gc?))
(jbr %set-continue)
%kernel-end
%horrible-heap-overflow
(adjspi b ($ -4))
(bici b ($ #b10000000) (d@r TASK (fx+ task/critical-count 3)))
(spri d nil-reg (d@r TASK task/doing-gc?))
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'heap-overflow-error)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP))
%undefined-effect
(movi d TP A2) ; template
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'handle-undefined-effect)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(adjspi b ($ -4))
(jump (@r TP))
))
(lap-template (0 0 -1 t stack %int-return-handler) ;86/12/24
%int-return
(ori b ($ #b01000000) (d@r TASK (fx+ task/critical-count 3))) ; disable int's
;; 16 = 2 (scratch regs) + 3 (extra p & s & task/scratch)
;; + 6 (pointer regs) + 1 (pc)
;; + 4 (hack top, pointers on stack, header, template)
(movi d (d@r SP 12) (d@r SP (* (+ *pointer-temps* *scratch-temps* 16) 4)))
(adjspi b ($ -20)) ; pop template, header, pointers on stack, hack top, pc
(movi d (tos) P)
(movi d (tos) A1)
(movi d (tos) A2)
(movi d (tos) A3)
(movi d (tos) AN)
(movi d (tos) TP)
(movi d ($ -3) S0)
%int-return-restore-loop ; restore temps
(movi d (tos) (index-d (@r TASK) S0))
(addi d ($ 1) S0)
(cmpi d ($ (fx/ temp-block-size 4)) S0)
(j> %int-return-restore-loop)
(movi d (tos) NARGS)
(movi d (tos) S0)
(bici b ($ #b01000000) (d@r TASK (fx+ task/critical-count 3)))
(ret ($ 0))
%int-return-handler
(spri d nil-reg AN)
(ret ($ 0)))
(define (clear-extra-registers) ;86/12/24
(lap ()
(movi d ($ -1) S0)
zero-loop ; restore temps
(movi d ($ 0) (index-d (@r TASK) S0))
(addi d ($ 1) S0)
(cmpi d ($ (fx/ temp-block-size 4)) S0)
(j> zero-loop)
(movi d ($ -2) NARGS)
(movi d (@r sp) tp)
(jump (@r tp))))
(lap-template (0 0 -1 t stack pc-check-return-handler) ;86/12/24
pc-check-return
(adjspi b ($ -4)) ; pop return address
(movi d A1 (tos)) ; code vector of pc
(addr (d@r A1 -2) (tos)) ; fixnumized code vector
(addr (label gc-template) (tos)) ; continuation
(movi d (d@r nil-reg slink/kernel) P)
(movi d (d@r P (static 'really-gc)) P)
(movi d (d@r p 2) p)
(movi d (d@r P -2) TP)
(jump (@r TP))
pc-check-return-handler
(spri d nil-reg AN)
(ret ($ 0)))
;;; sizes of gc template:
;;; pointer -- n registers + n temps + 1 extra + 2 code vector + tp
;;; scratch -- gc return address + 1 other + n registers + n temps
(lap-template ((+ *pointer-temps* *pointer-registers* 4) ;86/12/24
(+ *scratch-temps* *scratch-registers* 2)
-1 t stack gc-template-handler) ;; see gc.t
gc-template
(addr (label %post-gc-nary-setup) (d@r nil-reg slink/nary-setup))
(adjspi b ($ -4)) ; pop template
(movi d (tos) S0) ; pop old code (fixnum)
(movi d (tos) NARGS) ; pop relocated code
(cmpi d NARGS (d@r nil-reg slink/nil-car)) ; (NARGS is extra scratch)
(j= gc-continue) ; not relocated
(subi d ($ tag/extend) NARGS) ; fixnumize new code
(subi d S0 NARGS) ; delta pc
(addi d NARGS (d@r SP (* (+ *no-of-registers* 3) 4))) ; update pc
gc-continue
(movi d (tos) P)
(movi d (tos) A1)
(movi d (tos) A2)
(movi d (tos) A3)
(movi d (tos) AN)
(movi d (tos) TP)
(movi d ($ -1) S0)
restore-loop ; restore temps
(movi d (tos) (index-d (@r TASK) S0))
(addi d ($ 1) S0)
(cmpi d ($ (fx/ temp-block-size 4)) S0)
(j> restore-loop)
(movi d (tos) NARGS)
(movi d (tos) S0)
(ret ($ 0))
gc-template-handler
(spri d nil-reg AN)
(ret ($ 0)))
(lap-template (0 0 0 nil stack stack-base-handler) ;86/12/24
stack-base-template
(jump (*d@r nil-reg slink/undefined-effect))
stack-base-handler
(movi d (d@r nil-reg slink/kernel) AN)
(movi d (d@r AN (static 'handle-stack-base)) A1)
(movi d (d@r a1 2) a1)
(jump (*d@r nil-reg slink/dispatch-label)))
(define (lap-relocate frame old-tp new-tp offset) ;86/12/27
(lap ()
(movi d (d@r TASK 12) S0) ; offset (4th arg)
(movi d (index-b (d@r A1 2) S0) NARGS) ; code (NARGS is extra scratch)
(subi d A2 NARGS) ; code-offset
(addi d NARGS A3) ; new code
(movi d A3 (index-b (d@r A1 2) S0))
(movi d ($ -1) NARGS)
(movi d (@r sp) tp)
(jump (@r tp))))
(define (current-task) ;86/12/27
(lap ()
(spri d TASK A1)
(addi d ($ (fx+ %%task-header-offset 2)) A1) ; offset is negative !
(movi d ($ -2) NARGS)
(movi d (@r sp) tp)
(jump (@r tp))))
; debugger hacks
(define (@@ address) ; randomness ;86/12/27
(lap ()
(addi d ($ 2) A1)
(movi d ($ -2) NARGS)
(movi d (@r sp) tp)
(jump (@r tp))))
(define-foreign gc_interrupt (gc_interrupt) ignore) ;86/12/27
(define (crawl-exhibit-fault-frame frame) ;86/12/27
(cond ((not (foreign-fault-frame? frame)) ; foreign
(print-register frame 'p 3)
(print-register frame 'a1 4)
(print-register frame 'a2 5)
(print-register frame 'a3 6)
(print-register frame 'an 7)
(print-register frame 'tp 8))
(else
(format t " In foreign code; no information available~%"))))
(define (trace-fault-frame frame) ;86/12/27
(cond ((alt-bit-set? frame)
(move-object (make-pointer frame 0))) ; foreign cont
(else
(let ((tp (extend-elt frame 8))) ; old TP
(trace-pointers (make-pointer frame 2)
(fx+ *pointer-registers* 1)) ; trace registers
(trace-pointers ; trace temps
(make-pointer frame (fx+ *pointer-registers* 5))
; 5 = #point,hacktos,pc,ex-scr,scr
(fx+ *pointer-temps* 1))
(let ((ptrs (extend-elt frame 0)) ; trace top of stack
(size (fault-frame-slots frame)))
(trace-pointers (make-pointer frame (fx- size 1)) ptrs))
(if (eq? (extend-elt frame 1) 0) ; hack-top-of-stack?
(relocate-random-code frame 2 tp) ; relocate PC
(relocate-random-code frame 1 tp)))))) ; relocate top-of-stack
(define (relocate-random-code frame offset old-tp) ;86/12/27
(if (in-old-space? (extend-elt frame offset))
(lap-relocate frame
old-tp
(extend-elt frame (fx+ *pointer-registers* 3))
offset)))
(define (make-link-snapper value unit i)
(lap ()
(movi d (d@r nil-reg slink/snapper-freelist) p)
(cmpi d p (d@r nil-reg 1))
(j= cons-snapper-1)
(movi d (d@r p 1) an)
(movi d (d@r p -3) (d@r nil-reg slink/snapper-freelist))
(movi d (d@r nil-reg slink/pair-freelist) (d@r p -3))
(movi d p (d@r nil-reg slink/pair-freelist))
foobarfoo
(movi d a1 (d@r an 2))
(movi d a2 (d@r an 6))
(movi d a3 (d@r an 10))
(movi d an a1)
(movi d ($ -2) nargs)
(movi d (@r sp) tp)
(jump (@r tp))
cons-snapper-1
(addr (label link-snapper) an)
(movi d ($ 12) S0)
(jsr (label %make-extend))
(jbr foobarfoo)))
(define *link-snapper-template*
(lap-template (3 0 1 t heap handle-snapper)
link-snapper
(movi d p an)
(movi d (d@r p 2) p)
(movi w P S0)
(andi b ($ #b11) S0)
(cmpi b ($ tag/extend) S0) ; check ptr to closure is extend
(jn= %icall-bad-proc)
(movi d (d@r P -2) TP) ; fetch template header
(movi w TP S0)
(andi b ($ 3) S0) ; check header is extend
(cmpi b ($ tag/extend) S0)
(jn= %icall-bad-proc)
(cmpi b (d@r TP -2) ($ header/template)) ; check header is template
(jn= %icall-check-nary-l)
(cmpi b (d@r TP template/nargs) NARGS) ; check number of args
(j= snap-link)
(jbr %icall-wrong-nargs)
%icall-check-nary-l
(cmpi b (d@r TP -2) ($ (fx+ header/template 128))) ; nary if high bit set
(jn= %icall-bad-proc)
(cmpi b (d@r TP template/nargs) NARGS)
(j> %icall-wrong-nargs)
snap-link
(movi d an (d@r task task/extra-pointer))
(movi d (d@r an 10) s0)
(movi d (d@r an 6) an)
(movi d p (index-b (d@r an 2) s0))
(movi d (d@r nil-reg slink/pair-freelist) an)
(cmpi d an (d@r nil-reg 1))
(j= cons-pair)
(movi d (d@r an -3) (d@r nil-reg slink/pair-freelist))
consed-pair
(movi d (d@r task task/extra-pointer) (d@r an 1))
(movi d (d@r nil-reg slink/snapper-freelist) (d@r an -3))
(movi d an (d@r nil-reg slink/snapper-freelist))
(jump (@r TP))
cons-pair
(jsr (label %make-pair))
(jbr consed-pair)
handle-snapper
(spri d nil-reg AN)
(ret ($ 0))))